package org.yocastlong.mybatisplus.handle;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.yocastlong.mybatisplus.common.CommonConstants;
import org.yocastlong.mybatisplus.common.annotations.IgnoreLogin;
import org.yocastlong.mybatisplus.common.exceptions.NeedLoginException;
import org.yocastlong.mybatisplus.common.utils.HeaderContext;
import org.yocastlong.mybatisplus.pojo.bo.UserInfoBO;
import org.yocastlong.mybatisplus.service.AuthService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * @author 朱海龙
 * 2025/6/9 22:28
 */
public class HeaderInterceptor implements HandlerInterceptor {


    private AuthService authService;

    public HeaderInterceptor(AuthService authService) {
        this.authService = authService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return Boolean.TRUE;
        }
        final HandlerMethod handlerMethod = (HandlerMethod) handler;
        boolean             ignoreLogin   = handlerMethod.hasMethodAnnotation(IgnoreLogin.class);
        if (ignoreLogin) {
            return Boolean.TRUE;
        }

        final String token = request.getHeader(CommonConstants.header.token);
        if (StringUtils.isBlank(token)) {
            throw new NeedLoginException();
        }

        final UserInfoBO userInfoBO = authService.checkTokenAndGetUserInfo(token);

        if (Objects.isNull(userInfoBO)) {
            throw new NeedLoginException();
        }

        final String userId = userInfoBO.getUserId();
        HeaderContext.setUserId(userId);
        final String username = userInfoBO.getUsername();
        HeaderContext.setUsername(username);
        final String tenantId = userInfoBO.getTenantId();
        HeaderContext.setTenantId(tenantId);
        HeaderContext.setObject(CommonConstants.header.userInfoBO, userInfoBO);

        return Boolean.TRUE;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HeaderContext.reset();
    }
}
